<template>
  <div class="box">
    <div class="cancel_box" v-show="isVideo">
      <div class="cancel_text">
        <div class="cancel_item">
          <div
            class="cancel_time"
            :style="{ background: isSend ? 'rgb(255, 255, 255)' : 'rgb(241, 76, 76)' }"
          >
            <div class="loader">
              <div class="loader-inner">
                <div
                  class="loader_item"
                  :class="{ 'loader-block': isSend }"
                  v-for="item in 24"
                ></div>
              </div>
            </div>
          </div>
          <div class="cancel_ts">{{ timeText }}</div>
        </div>
      </div>
      <div class="cancel_button">
        <div class="sz">
          <i class="iconfont">&#xe624;</i>
          <div class="sz_text">上划取消发送</div>
        </div>
        <el-icon><Microphone /></el-icon>
      </div>
    </div>
    <div
      class="talk_right_box"
      v-loading="loading"
      element-loading-text="加载中..."
      :element-loading-spinner="svg"
      element-loading-svg-view-box="-10, -10, 50, 50"
      element-loading-background="rgba(122, 122, 122, 0.8)"
    >
      <div class="content_box" ref="content_box">
        <div class="content" ref="content">
          <div class="talk" v-for="(item, index) in talklist" :key="index">
            <!-- 问 -->
            <div class="talk_item talk_q" v-if="item.type == 0" v-scrollToBottom>
              <div class="tall_text">
                <!-- <div class="talk_name">{{ item.time }}</div> -->
                <div class="text_item">
                  <div
                    class="text_item_item"
                    style="background-color: #66b1ff; padding: 10px 20px 10px; color: white"
                  >
                    {{ item.text }}

                    <div class="file_box">
                      <div
                        class="file_item"
                        v-for="(e, y) in item.fileList"
                        :key="y"
                        @click="download(e)"
                      >
                        <div class="file_icon">
                          <img src="@/assets/images/OIP-C (2).jpg" alt="" />
                        </div>
                        <div class="file_text">
                          <div class="file_name">{{ e.name }}</div>
                          <div class="file_size">{{ e.size }} M</div>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <div class="tall_img">
                <img src="@/assets/images/download.png" alt="" />
              </div>
            </div>
            <!-- 答 -->

            <!-- 答,文字 -->
            <div class="talk_item" v-if="item.type == 1" v-scrollToBottom>
              <div style="display: flex">
                <div class="tall_img">
                  <img src="@/assets/images/answer.png" alt="" />
                </div>
                <div class="tall_text">
                  <div class="talk_name">
                    <div class="talk_name_item">智能排障助手</div>
                  </div>
                  <div class="text_item">
                    <div class="text_item_item" v-if="item.shows">
                      <div class="cursor_loding">{{ thinkTEXT }} <CursorDom></CursorDom></div>
                    </div>

                    <div class="text_item_item" v-if="!item.shows && item.sid == 0">
                      {{ item.text }}
                    </div>
                    <div class="text_item_item" v-if="!item.shows && item.sid != 0">
                      <div
                        style="
                          color: #8b8b8b;
                          border-left: 2px solid #e5e5e5;
                          padding-left: 10px;
                          border-radius: 1px;
                        "
                        v-html="item.Thinktext"
                      ></div>

                      <div
                        style="padding: 10px 0px; white-space: pre-wrap"
                        class="markdown_box"
                        v-html="md(item.text)"
                      ></div>
                    </div>

                    <div
                      class="text_item_item"
                      v-if="item.showThink"
                      style="transform: translateY(-25px)"
                    >
                      <div class="cursor_loding" style="color: #8b8b8b">
                        {{ thinkTEXT }} <CursorDom :color="'#8b8b8b'"></CursorDom>
                      </div>
                    </div>
                    <div class="Collection-of-buttons">
                      <!-- <div class="like_buttons" @click="like(item.id)">
                        <el-tooltip effect="dark" content="重新生成" placement="top">
                          <img :src="Refresh" class="like_icon" alt="" />
                        </el-tooltip>
                      </div> -->
                      <div class="like_buttons" @click="copyText(item.text)">
                        <el-tooltip effect="dark" content="复制示例" placement="top">
                          <img :src="Copy" class="like_icon" alt="" />
                        </el-tooltip>
                      </div>
                      <div class="like_buttons" @click="fuckFn">
                        <img
                          :src="Fuck"
                          class="like_icon"
                          alt=""
                          style="width: 17px; margin-top: 2px"
                        />
                        <div class="like_text">举报</div>
                      </div>
                      <!-- <div class="like_buttons" @click="deleteFn">
                        <img :src="Delete" class="like_icon" alt="" />
                        <div class="like_text">删除</div>
                      </div> -->
                      <div class="like_buttons" @click="like(item.id)">
                        <!-- <el-tooltip effect="dark" content="更多推荐" placement="top"> -->
                        <img :src="More" class="like_icon" alt="" />
                        <!-- </el-tooltip> -->
                      </div>
                      <div class="like_buttons">
                        <div class="slot"></div>
                      </div>
                      <div class="like_buttons" @click="likeFn">
                        <el-tooltip effect="dark" content="喜欢" placement="top">
                          <img :src="Like" class="like_icon" alt="" />
                        </el-tooltip>
                      </div>
                      <div class="like_buttons" @click="nolikeFn">
                        <el-tooltip effect="dark" content="不喜欢" placement="top">
                          <img :src="Nolike" class="like_icon" alt="" />
                        </el-tooltip>
                      </div>
                    </div>

                    <div class="home-LikeDom" v-if="likeFlag">
                      <LikeDom :handleReset="handleReset"></LikeDom>
                    </div>

                    <div class="home-LikeDom" v-if="nolikeFlag">
                      <NoLikeDom :handleReset="handleReset"></NoLikeDom>
                    </div>

                    <div
                      class="like_allbox"
                      :style="{
                        justifyContent:
                          item.questions && item.questions.length > 0 ? 'space-between' : 'flex-end'
                      }"
                    >
                      <!-- v-if="item.questions && item.questions.length > 0" -->
                      <div class="more_question_box">
                        <!-- <Probe></Probe> -->
                        <div></div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <!-- (暂时不用) -->
      <!-- <el-button @click="recPlay()" style="display: none">播放</el-button> -->
      <!-- ==== -->
      <div class="input_box" v-show="!isShow">
        <!-- <div class="upload_box"> -->
        <!-- <div class="upload_button" @click="isShow = true">
            <el-icon><Mic /></el-icon>
            <span>语音识别</span>
          </div> -->

        <!-- <div class="upload_button" @click="handleSubmit">
            <input
              type="file"
              name="avatar"
              accept="image/gif,image/jpeg,image/jpg,image/png"
              style="display: none"
              @change="changeImage($event)"
              ref="avatarInput"
            />
            <el-icon><FolderOpened /></el-icon>
            <span>上传附件</span>
          </div> -->
        <!-- <div
            class="upload_button"
            @click="
              () => {
                router.push('/menu/home')
              }
            "
          >
            <el-icon><FolderAdd /></el-icon>
            <span>新对话</span>
          </div> -->
        <!-- </div> -->

        <div class="input_item">
          <div class="file_box">
            <div class="file_item" v-for="(e, y) in TalkfileList" :key="y">
              <div class="del_box" @click="fileDel(e)">X</div>
              <div class="file_icon">
                <img src="@/assets/images/OIP-C (2).jpg" alt="" />
              </div>
              <div class="file_text">
                <div class="file_name">{{ e.name }}</div>
                <div class="file_size">{{ e.size }} M</div>
              </div>
            </div>
          </div>
          <div class="input">
            <div
              ref="textarea"
              @keydown="handleShiftEnter"
              @input="updateSendStatus"
              contenteditable="true"
              placeholder="请输入内容... (Shift + Enter = 换行)"
              class="txt-word"
            ></div>
          </div>
          <div class="button_box">
            <img
              :src="isTextValue && !isq ? NewSend : NoSend"
              class="image"
              @click="send()"
              :class="isTextValue && !isq ? '' : 'disabled-image'"
              alt=""
            />
          </div>
        </div>
      </div>

      <div class="video_box" v-show="isShow">
        <div class="keyboard_box" @click="isShow = false">
          <i class="iconfont keyboard_inco">&#xe661;</i>
        </div>
        <div class="video_item">
          <div class="video_keyboard">按住说话</div>
          <div class="video_keyboard_copy" v-if="!isq" v-drag ref="myDiv" @mousedown="down"></div>
          <div class="video_keyboard_copy" v-if="isq"></div>
        </div>
      </div>
    </div>
    <Report ref="reportRef"></Report>
    <DeleteDom ref="deleteRef"></DeleteDom>
  </div>
</template>
<script setup lang="ts">
import { loadNDJSON } from './ndjson/index.js'
import { loadCheckContent } from '@/views/talk/check/index.js'
import md from './md/markdown.js'
import Recorder from 'recorder-core'
import 'recorder-core/src/engine/mp3'
import 'recorder-core/src/engine/mp3-engine'
import 'recorder-core/src/engine/wav'

import cache from '@/utils/cache'
import { ref, onMounted, reactive, h, onBeforeMount, onBeforeUnmount, nextTick } from 'vue'
import { getVoiceText, sendSms, getTokenInfo, sendQuestion } from '@/api/talk'

import CursorDom from '@/components/CursorDom/index.vue'
import { FormInstance, FormRules, ElNotification, UploadUserFile, UploadProps } from 'element-plus'
import Probe from './components/probe.vue'
import Copy from '@/assets/png/copy.png'
import NewSend from '@/assets/png/newsend.png'
import NoSend from '@/assets/png/nosend.png'
import Refresh from '@/assets/png/refresh.png'
import Delete from '@/assets/png/delete.png'
import Like from '@/assets/png/like.png'
import Nolike from '@/assets/png/nolike.png'
import Fuck from '@/assets/png/fuck.png'
import More from '@/assets/png/more.png'
import { useRouter } from 'vue-router'
import Report from './components/report.vue'
import DeleteDom from './components/delete.vue'
import LikeDom from './components/like.vue'
import NoLikeDom from './components/nolike.vue'
import { ElMessage } from 'element-plus'
import axios from 'axios'
import { useBeforeTalkMOCK } from './mock.js'

const router = useRouter()

type TalkType = Array<{
  sid: any //前端记录id
  id?: string //后端真实id
  type: number //0是问，1是答
  shows?: boolean //是否显示光标
  text?: string //文本
  Thinktext?: string //Think文本
  time: any
  questions?: string[]
  fileList?: any[] //附件列表
}>

let rec: any //实例化录音对象
let recBlob: any //存储录音文件
let wave: any //绘制波形（暂时没有）
const recwave = ref(null) //绘制波形的div（暂时没有）
const synth = window.speechSynthesis
const msg = new SpeechSynthesisUtterance()
const loading = ref(false)
const thinkTEXT = ref('正在努力为您查询')
const thinkFlag = ref(false) //是否正在思考--接口返回的type为6
const svg = `
        <path class="path" d="
          M 30 15
          L 28 17
          M 25.61 25.61
          A 15 15, 0, 0, 1, 15 30
          A 15 15, 0, 1, 1, 27.99 7.5
          L 15 15
        " style="stroke-width: 4px; fill: rgba(0, 0, 0, 0)"/>
        `
const btnstyle = ``
const textarea = ref(null) //输入框
let isq = ref(false) //判断是否完成回答
const isShow = ref(false) //切换输入框和语音录入
const myDiv = ref(null) // 按住说的悬浮div
const isVideo = ref(false) //开始录音
const seconds = ref(0) // 计时器秒数
const isRunning = ref(false) // 计时器是否在运行的状态
let timer = null // 用于存储计时器的 ID
const timeText = ref('开始') // 格式化后的时间文本
const isSend = ref(true) // 是否发送
const reportRef = ref(null)
const deleteRef = ref(null)
const likeFlag = ref(false) // 点赞标志
const nolikeFlag = ref(false) // 点踩标志
const isTextValue = ref(false) // 输入框是否有值

const sessionId = ref(getID()) //对话id
const content_box = ref(null)
const content = ref(null)
//对话列表
let talklist = ref<TalkType>([
  {
    sid: '0',
    id: null,
    type: 1, //0是问，1是答
    shows: false, //是否显示光标
    Thinktext: '',
    text: `智能排障助手已就位🚀！需排查 “源 IP→目的 IP + 端口不通”？请提供源 IP、目的 IP 及端口📌，即刻启动检测⚡，快速反馈结果哦～

📝 信息输入格式：
源 IP：[你的源IP地址]
目的 IP：[目标IP地址]
端口：[端口号]

输入示例：
源 IP：134.80.251.4
目的 IP：134.80.251.9
端口：tcp/80

⚡ 输入上述信息后，我将立即启动检测并反馈结果！
`,
    time: getTime(),
    questions: []
  }
])
const TalkfileList = ref([]) //对话文件列表
const timers = ref(null) // 页面超时计时器
const avatarInput = ref(null) //上传文件的input
onBeforeMount(() => {})

onMounted(() => {
  cache.local.remove('token') //刷新删除token
  removeStyles()
  // exit()
})
// 在组件卸载前移除事件监听器
onBeforeUnmount(() => {
  window.removeEventListener('mousemove', handleMouseMove)
  window.removeEventListener('keydown', handleKeyDown)
  window.removeEventListener('wheel', handleWheel)
})

// 处理文件hooks
const useFileHooks = () => {
  //触发上传附件
  function handleSubmit() {
    avatarInput.value.click()
  }
  // 当文件域的内容改变的时候获取里面的文件信息对象
  function changeImage(e: any) {
    const file = e.target.files[0]
    if (!file) return // 如果没有文件，直接返回
    let reader = new FileReader()
    reader.onload = function (e) {
      // console.log(e.target.result) // 读取文件的结果
      const fileList = e.target.result // 获取文件内容base64
      const fileName = file.name // 获取文件名称
      const fileSize = file.size // 获取文件大小
      const fileType = file.type // 获取文件类型
      // 将文件大小转换为MB（兆字节）
      const fileSizeInMB = (fileSize / (1024 * 1024)).toFixed(2) // 保留两位小数
      const fileObj = {
        id: getID(), // 随机生成一个唯一的 ID
        name: fileName,
        size: fileSizeInMB,
        type: fileType,
        url: fileList,
        raw: file // 原始文件对象
      }
      // console.log(fileObj) // 打印文件对象

      TalkfileList.value.push(fileObj) // 将文件对象添加到列表中
    }
    reader.readAsDataURL(file) // 读取文件内容
  }
  // 下载文件(通过base64下载)
  function download(item: any) {
    console.log(item)
    const base64Data = item.url // 替换成实际的 base64 数据
    const link = document.createElement('a')
    link.href = base64Data
    link.download = item.name // 设置下载的文件名
    link.click() // 触发点击事件进行下载
  }

  // 删除暂存文件
  function fileDel(e: any) {
    // console.log(e)
    const index = TalkfileList.value.findIndex((item) => item.id == e.id)
    if (index !== -1) {
      TalkfileList.value.splice(index, 1) // 删除文件对象
    }
  }

  return {
    handleSubmit,
    changeImage,
    download,
    fileDel
  }
}

const { handleSubmit, changeImage, download, fileDel } = useFileHooks()

// 处理鼠标移动
const handleMouseMove = (event: any) => {
  startTimers()
}
// 处理键盘按键
const handleKeyDown = (event: any) => {
  startTimers()
}
// 处理滚轮滑动
const handleWheel = (event: any) => {
  startTimers()
}
//长时间未操作强制刷新
function exit() {
  startTimers()
  window.addEventListener('mousemove', handleMouseMove)
  window.addEventListener('keydown', handleKeyDown)
  window.addEventListener('wheel', handleWheel)
}
//页面刷新定时器
function startTimers() {
  // 清除上一个定时器
  if (timers.value) {
    clearTimeout(timers.value)
  }

  // 设置一个新的定时器
  timers.value = setTimeout(
    function () {
      console.log('60分钟已过！')
      // 执行的操作
      location.reload()
    },
    60 * 60 * 1000
    // 10 * 1000
  )
}

// 格式化时间的函数
function formatTime(time: number) {
  const minutes = Math.floor(time / 60) // 计算分钟数
  const secs = time % 60 // 计算秒数
  return `${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}` // 返回 MM:SS 格式的字符串
}

const useBtnHooks = () => {
  const fuckFn = () => {
    reportRef.value.handleVisible()
  }
  const deleteFn = () => {
    deleteRef.value.handleVisible()
  }
  const likeFn = () => {
    nolikeFlag.value = false
    likeFlag.value = !likeFlag.value // 切换点赞标志
  }

  const nolikeFn = () => {
    likeFlag.value = false
    nolikeFlag.value = !nolikeFlag.value // 切换点踩标志
  }

  const handleReset = () => {
    likeFlag.value = false
    nolikeFlag.value = false
  }

  const copyText = (text) => {
    // 要复制的内容（固定文本，也可根据需要改为接收的text参数）
    const copyContent = `源 IP：172.50.0.254 目的 IP：172.60.0.254 端口：tcp/80`

    // 优先使用 Clipboard API（高版本浏览器）
    if (navigator.clipboard && window.isSecureContext) {
      navigator.clipboard
        .writeText(copyContent)
        .then(() => {
          ElMessage({
            message: '复制成功',
            type: 'success'
          })
        })
        .catch((err) => {
          console.error('Clipboard API 复制失败，降级处理:', err)
          fallbackCopy(copyContent) // 降级到传统方法
        })
    } else {
      // 低版本浏览器直接使用传统方法
      fallbackCopy(copyContent)
    }
  }

  // 传统复制方法（兼容低版本浏览器）
  const fallbackCopy = (content) => {
    // 创建临时 textarea 元素
    const textarea = document.createElement('textarea')
    textarea.value = content
    // 设置为不可见（不影响页面布局）
    textarea.style.position = 'absolute'
    textarea.style.left = '-9999px'
    textarea.style.opacity = '0'
    // 添加到页面
    document.body.appendChild(textarea)
    // 选中内容
    textarea.select()
    textarea.setSelectionRange(0, content.length) // 兼容移动设备

    try {
      // 执行复制命令
      const successful = document.execCommand('copy')
      if (successful) {
        ElMessage({
          message: '复制成功',
          type: 'success'
        })
      } else {
        throw new Error('复制命令执行失败')
      }
    } catch (err) {
      console.error('传统方法复制失败:', err)
      ElMessage({
        message: '复制失败，请手动复制',
        type: 'error'
      })
    } finally {
      // 移除临时元素
      document.body.removeChild(textarea)
    }
  }

  return { fuckFn, deleteFn, likeFn, nolikeFn, handleReset, copyText }
}
const { fuckFn, deleteFn, likeFn, nolikeFn, handleReset, copyText } = useBtnHooks()

// 语音识别相关的hooks
const useVoiceHooks = () => {
  // 打开麦克风
  function recOpen() {
    //创建录音对象
    rec = Recorder({
      type: 'wav', //录音格式，可以换成wav等其他格式
      sampleRate: 16000, //录音的采样率，越大细节越丰富越细腻
      bitRate: 16, //录音的比特率，越大音质越好
      onProcess: (
        buffers: any,
        powerLevel: any,
        bufferDuration: any,
        bufferSampleRate: any,
        newBufferIdx: any,
        asyncEnd: any
      ) => {
        //录音实时回调，大约1秒调用12次本回调
        //可实时绘制波形，实时上传（发送）数据
        if (wave) {
          wave.input(buffers[buffers.length - 1], powerLevel, bufferSampleRate)
        }
      }
    })
    if (!rec) {
      alert('当前浏览器不支持录音功能！')
      return
    }
    //打开录音，获得权限
    rec.open(
      () => {
        //console.log('录音已打开')
        if (recwave.value) {
          //创建音频可视化图形绘制对象
          wave = Recorder.WaveView({ elem: recwave.value })
        }
        recStart()
      },
      (msg: any, isUserNotAllow: any) => {
        //用户拒绝了录音权限，或者浏览器不支持录音
        // console.log((isUserNotAllow ? 'UserNotAllow，' : '') + '无法录音:' + msg)
      }
    )
  }
  // 开始录音
  function recStart() {
    //console.log(!rec)
    if (!rec) {
      console.error('未打开录音')
      return
    } else {
      rec.start()
    }

    //console.log('已开始录音')
  }
  // 结束录音
  function recStop() {
    if (!rec) {
      console.error('未打开录音')
      return
    }
    rec.stop(
      (blob: any, duration: any) => {
        //blob就是我们要的录音文件对象，可以上传，或者本地播放
        recBlob = blob
        //简单利用URL生成本地文件地址，此地址只能本地使用，比如赋值给audio.src进行播放，赋值给a.href然后a.click()进行下载（a需提供download="xxx.mp3"属性）
        const localUrl = (window.URL || window.webkitURL).createObjectURL(blob)
        //console.log('录音成功', blob, localUrl, '时长:' + duration + 'ms')
        if (isSend.value) {
          uploadfile(blob) //把blob文件上传到服务器
        }

        rec.close() //关闭录音，释放录音资源，当然可以不释放，后面可以连续调用start
        rec = null
      },
      (err: any) => {
        console.error('结束录音出错：' + err)
        rec.close() //关闭录音，释放录音资源，当然可以不释放，后面可以连续调用start
        rec = null
      }
    )
  }

  // 上传录音
  function uploadfile(blob: any) {
    // console.log(blob)
    loading.value = true
    getVoiceText({ file: blob }).then((res: any) => {
      if (res.code == 200) {
        loading.value = false
        send(res.data)
      } else {
        ElNotification.error({ title: '请重新登录' })

        setTimeout(() => {
          location.reload()
        }, 1000)
      }
    })
    //console.log('video.wav', blob)
  }
  // 开始录音计时
  const startTimer = () => {
    if (!isRunning.value) {
      isRunning.value = true
      timer = setInterval(() => {
        seconds.value++
        timeText.value = formatTime(seconds.value) // 更新格式化后的时间文本
      }, 1000)
    }
  }

  // 暂停录音计时
  const stopTimer = () => {
    clearInterval(timer)
    timer = null
    isRunning.value = false
  }

  // 重置计时器的函数
  const resetTimer = () => {
    clearInterval(timer) // 清除计时器
    seconds.value = 0 // 重置秒数为 0
    timeText.value = formatTime(seconds.value) // 重置格式化后的时间文本
    isRunning.value = false // 重置运行状态为 false
  }

  return { recOpen, recStart, recStop, uploadfile, startTimer, stopTimer, resetTimer }
}

const { recOpen, recStart, recStop, uploadfile, startTimer, stopTimer, resetTimer } =
  useVoiceHooks()

// 处理鼠标按下事件
function down(e: MouseEvent) {
  isVideo.value = true //开始录音
  startTimer() // 开始录音计时
  timeText.value = formatTime(seconds.value) // 提示信息赋值
  recOpen() //打开录音
  // 鼠标移动
  const onMouseMove = () => {
    //console.log(myDiv.value.style.top)
    if (parseFloat(myDiv.value.style.top) < -50) {
      //console.log('超出')
      rec.pause() //暂停录音
      isSend.value = false
      timeText.value = '松开鼠标，取消发送' // 提示信息
      stopTimer() // 停止计时
    } else {
      //console.log('恢复')
      rec.resume() //恢复继续录音
      isSend.value = true
      timeText.value = formatTime(seconds.value)
      startTimer() // 开始计时
    }
  }

  // 鼠标松开
  const onMouseUp = () => {
    //console.log('鼠标松开')
    isVideo.value = false
    resetTimer() // 清除计时器
    recStop() //结束录音

    // 清理鼠标移动事件监听器
    document.removeEventListener('mousemove', onMouseMove)
    document.removeEventListener('mouseup', onMouseUp)
  }

  // 添加鼠标移动和鼠标松开事件监听器
  document.addEventListener('mousemove', onMouseMove)
  document.addEventListener('mouseup', onMouseUp)
}
//发送推荐问题
function question(e: string) {
  send(e)
}
// beforeTalk 问答开始前 需要判断一下

const useBeforeTalk = async () => {
  const params = { front_session_id: sessionId.value, ask_content: textarea.value.innerText }
  // 134.84.22.224
  const apiUrl = import.meta.env.VITE_APP_BASE_APIURL
  const response = await axios.post(`${apiUrl}/api/intelliTroubleshootingAsk`, params)
  return response
}
//提交问题
async function send(obj: any = '') {
  if (!obj) {
    if (!textarea.value.innerText) {
      ElNotification({
        title: '提示',
        message: h('i', { style: 'color: teal' }, '请输入内容!')
      })
      return
    }
  }
  // //console.log(isq.value)
  if (isq.value) {
    ElNotification({
      title: '提示',
      message: h('i', { style: 'color: teal' }, '请等待回答完毕!')
    })

    return
  }
  const qobj = {
    sid: getID(),
    type: 0,
    text: obj ? obj : textarea.value.innerText,
    time: getTime(),
    fileList: TalkfileList.value ? TalkfileList.value : []
  }
  talklist.value.push(qobj)

  // =============
  const aobj = {
    sid: getID(),
    type: 1,
    text: '',
    Thinktext: '',
    shows: true,
    time: getTime()
  }
  talklist.value.push(aobj)

  isq.value = true

  let b = {
    session_id: sessionId.value,
    qtime: qobj.time,
    atime: aobj.time,
    text: obj ? obj : textarea.value.innerText,
    fileList: TalkfileList.value ? TalkfileList.value : []
  }
  let data = {
    list: []
  }
  data.list.push(b)

  const response = await useBeforeTalk()

  // const response = await useBeforeTalkMOCK() // mock数据

  // console.log('response', response)

  if (response.data.flag == 1) {
    textarea.value.innerText = ''
    TalkfileList.value = [] //清空文件列表
    // avatarInput.value.value = ''

    const apiUrl = import.meta.env.VITE_APP_BASE_APIURL
    try {
      await loadNDJSON(
        `${apiUrl}/api/intelliTroubleshootingCheck`,
        renderData,
        aobj.sid,
        sessionId.value
      )
      isq.value = false
    } catch (error) {
      isq.value = false
      console.error('Error loading NDJSON data:', error)
    }
  } else {
    isq.value = false
    talklist.value[talklist.value.length - 1].text = response.data.result || '请检查输入的格式信息'
    talklist.value[talklist.value.length - 1].shows = false
  }

  // ======================
}
// 渲染回调函数
const renderData = (res: any, sid: any) => {
  // console.log('res', res.data)
  const {
    data: { content, think, type, id, questions }
  } = res
  const index = talklist.value.findIndex((item) => item.sid == sid)

  // 判断当前流式输出是否为思维过程
  if (res.data.think && res.data.type == 5) {
    talklist.value[index].Thinktext = talklist.value[index].Thinktext + content
  } else if (!res.data.think && res.data.type == 5) {
    talklist.value[index].text = talklist.value[index].text + content
  }

  // 判断当前是否是接口存在卡顿
  if (type == 6) {
    thinkTEXT.value = content
    talklist.value[index].showThink = true
  } else {
    talklist.value[index].showThink = false
  }

  talklist.value[index].shows = false

  if (res.data.is_last) {
    talklist.value[index].id = id
    talklist.value[index].questions = questions ? questions : []
    this.loading = false
  }

  // console.log(talklist.value)
  scrollTop()
}

//页面滚动
function scrollTop() {
  nextTick(() => {
    content_box.value.scrollTop = content.value.scrollHeight
  })
}
//获取时间
function getTime() {
  const now = new Date()
  const year = now.getFullYear()
  const month = now.getMonth() + 1 // 月份从0开始，所以需要加1
  const day = now.getDate()
  const hours = now.getHours().toString().padStart(2, '0') // 保证两位数
  const minutes = now.getMinutes().toString().padStart(2, '0') // 保证两位数
  const seconds = now.getSeconds().toString().padStart(2, '0') // 保证两位数

  const formattedDate = `${year}/${month}/${day} ${hours}:${minutes}:${seconds}`
  return formattedDate
}
//唯一id
function getID() {
  return Date.now().toString(36) + Math.random().toString(36).substr(2)
}
//回车键
function handleShiftEnter(event: any) {
  if (!event.shiftKey && event.keyCode === 13) {
    event.preventDefault() // 阻止默认的换行行为
    // 执行其他操作，例如在普通 Enter 键时插入换行符或执行其他逻辑
    send()
    // console.log('回车')
  }
  if (event.shiftKey && event.keyCode === 13) {
    // 执行自定义的换行逻辑，确保光标放置在最后
    const range = window.getSelection().getRangeAt(0)
    const br = document.createElement('br')
    range.deleteContents()
    range.insertNode(br)
    range.setStartAfter(br)
    range.setEndAfter(br)
    range.collapse(false)
    textarea.value.scrollTop = textarea.value.scrollHeight
    // //console.log('shift+回车')
  }
}

const updateSendStatus = () => {
  isTextValue.value = textarea.value.innerText.trim() == '' ? false : true
}

//清除输入框样式
function removeStyles(): void {
  const contentEditableDiv = document.querySelector('div[contenteditable="true"]') as HTMLDivElement

  if (contentEditableDiv) {
    contentEditableDiv.addEventListener('paste', function (e: ClipboardEvent) {
      // //console.log(e);
      e.stopPropagation()
      e.preventDefault()

      let text = ''
      const event = e as ClipboardEvent

      if (event.clipboardData && event.clipboardData.getData) {
        text = event.clipboardData.getData('text/plain')
      } else if (window.Clipboard && (window.Clipboard as any).getData) {
        text = (window.Clipboard as any).getData('Text')
      }

      if (document.queryCommandSupported('insertText')) {
        document.execCommand('insertText', false, text)
      } else {
        document.execCommand('paste', false, text)
      }
    })
  } else {
    console.warn('No div with contenteditable="true" found.')
  }
}
// 本地播放录音(暂时不用)
function recPlay() {
  //本地播放录音试听，可以直接用URL把blob转换成本地播放地址，用audio进行播放
  const localUrl = URL.createObjectURL(recBlob)
  const audio = document.createElement('audio')
  audio.controls = true
  document.body.appendChild(audio)
  audio.src = localUrl
  audio.style.display = 'none'
  audio.play() //这样就能播放了
  //注意不用了时需要revokeObjectURL，否则霸占内存
  setTimeout(function () {
    URL.revokeObjectURL(audio.src)
  }, 5000)
}
</script>
<style>
.cursor {
  display: inline-block;
  width: 3px;
  height: 15px;
  background-color: black;
  animation: cursor-blink 1s infinite;
}

.disabled-image {
  cursor: not-allowed; /* 鼠标样式改为不可用 */
  pointer-events: none; /* 禁止点击事件 */
}

@keyframes cursor-blink {
  0% {
    opacity: 0;
  }

  49% {
    opacity: 0;
  }

  50% {
    opacity: 1;
  }
}
/* 隐藏滚动条 */
::-webkit-scrollbar {
  display: none;
}

.list-enter-active,
.list-leave-active {
  transition: all 0.5s;
}

.list-enter,
.list-leave-to {
  opacity: 0;
  transform: translateY(30px);
}
</style>
<style scoped lang="less">
.box {
  height: 100vh;
  // width: 414px;
  width: 100%;
  background-color: #fff;
  display: flex;
  flex-direction: column;
  border-radius: 10px;
  overflow: hidden;

  .login_box {
    width: 100%;
    height: 100%;
    background-color: #0009;
    position: absolute;
    top: 0;
    left: 0;
    z-index: 998;
    display: flex;
    align-items: center;
    justify-content: center;
    .login_item {
      width: 350px;
      height: 305px;
      background-color: #fff;
      border-radius: 8px;
      padding: 20px 25px;
      box-sizing: border-box;
      position: relative;
      .x_box {
        position: absolute;
        top: 0px;
        left: calc(100% - 40px - 20px);
        width: 40px;
        height: 42px;
        background-color: #409eff;
        color: #fff;
        font-weight: bold;
        text-align: center;
        line-height: 42px;
        border-bottom-left-radius: 50%;
        border-bottom-right-radius: 50%;
        font-size: 16px;
        cursor: pointer;
        &:hover {
          opacity: 0.95;
        }
      }
      .login_item_title {
        font-size: 23px;
        color: #5a5a5a;
        font-weight: bold;
        letter-spacing: 1px;
      }
      .login_item_form {
        margin-top: 30px;
        width: 100%;
        .mobile_code {
          margin-top: 30px;
          position: relative;
          ::v-deep .el-input__inner {
            padding-right: 85px !important;
          }
          .mobile_code_box {
            position: absolute;
            top: 0px;
            left: 70%;
            font-size: 13px;
            color: #595959;

            cursor: pointer;
            z-index: 999;
            width: 89px;

            &:hover {
              color: #7f7f7f;
            }
          }
        }
      }
      .login_item_button_box {
        width: 100%;
        display: flex;
        align-items: center;
        justify-content: center;
        margin-top: 33px;
        .login_item_button {
          width: 100%;
          height: 44px;
          color: #fff;
          border-radius: 6px;
          display: flex;
          align-items: center;
          justify-content: center;
          font-size: 13px;
          background-color: #409eff;
          letter-spacing: 1px;
          font-weight: bold;
          cursor: pointer;
          &:hover {
            opacity: 0.9;
          }
        }
      }
    }
  }
  .cancel_box {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: #0009;
    z-index: 998;
    display: flex;
    flex-direction: column;
    .cancel_text {
      width: 100%;
      height: calc(100% - 75px);
      display: flex;
      justify-content: center;
      align-items: center;
      .cancel_item {
        width: 224px;
        .cancel_time {
          height: 98px;
          background-color: #fff;
          text-align: center;
          border-radius: 10px;

          .loader {
            display: flex;
            justify-content: center;
            align-items: center;
            width: 100%;
            height: 100%;
            position: relative;
          }

          .loader:before {
            content: '';
            position: absolute;
            top: -10px;
            left: -10px;
            right: -10px;
            bottom: -10px;
            border-radius: 50%;
          }

          .loader-inner {
            display: flex;
            justify-content: center;
            align-items: center;
            position: relative;
          }

          .loader-block {
            animation: loader 5s infinite;
          }
          .loader_item {
            display: inline-block;
            width: 3px;
            height: 7px;
            margin: 2px;
            background-color: #000;
          }
          .loader-block:nth-child(1) {
            animation-delay: 0.2s;
          }

          .loader-block:nth-child(2) {
            animation-delay: 0.4s;
          }

          .loader-block:nth-child(3) {
            animation-delay: 0.6s;
          }

          .loader-block:nth-child(4) {
            animation-delay: 0.8s;
          }

          .loader-block:nth-child(5) {
            animation-delay: 1s;
          }

          .loader-block:nth-child(6) {
            animation-delay: 1.2s;
          }

          .loader-block:nth-child(7) {
            animation-delay: 1.4s;
          }

          .loader-block:nth-child(8) {
            animation-delay: 1.6s;
          }

          .loader-block:nth-child(9) {
            animation-delay: 1.8s;
          }

          .loader-block:nth-child(10) {
            animation-delay: 2s;
          }

          .loader-block:nth-child(11) {
            animation-delay: 2.2s;
          }

          .loader-block:nth-child(12) {
            animation-delay: 2.4s;
          }

          .loader-block:nth-child(13) {
            animation-delay: 2.6s;
          }

          .loader-block:nth-child(14) {
            animation-delay: 2.8s;
          }

          .loader-block:nth-child(15) {
            animation-delay: 3s;
          }

          .loader-block:nth-child(16) {
            animation-delay: 3.2s;
          }

          .loader-block:nth-child(17) {
            animation-delay: 3.4s;
          }

          .loader-block:nth-child(18) {
            animation-delay: 3.6s;
          }

          .loader-block:nth-child(19) {
            animation-delay: 3.8s;
          }

          .loader-block:nth-child(20) {
            animation-delay: 4s;
          }

          .loader-block:nth-child(21) {
            animation-delay: 4.2s;
          }

          .loader-block:nth-child(22) {
            animation-delay: 4.4s;
          }

          .loader-block:nth-child(23) {
            animation-delay: 4.6s;
          }

          .loader-block:nth-child(24) {
            animation-delay: 4.8s;
          }

          @keyframes loader {
            0% {
              transform: scale(1);
              box-shadow: 0 0 40px rgb(53, 143, 246);
            }

            13% {
              transform: scale(1, 4);
              box-shadow: 0 0 60px rgb(53, 143, 246);
            }

            26% {
              transform: scale(1);
              box-shadow: 0 0 40px rgb(53, 143, 246);
            }
          }
        }
        .cancel_ts {
          width: 100%;
          font-size: 16px;
          color: #000;
          text-align: center;
          margin-top: 10px;
          letter-spacing: 1px;
        }
      }
    }
    .cancel_button {
      width: 100%;
      height: 75px;
      background-color: #fff;
      border-top-left-radius: 50%;
      border-top-right-radius: 50%;
      display: flex;
      align-items: center;
      justify-content: center;
      position: relative;
      .sz {
        position: absolute;
        top: -65px;
        left: 0%;
        display: flex;
        align-items: center;
        justify-content: center;
        width: 100%;
        .sz_text {
          color: #fff;
          font-size: 15px;
          letter-spacing: 1.5px;
          margin-left: 5px;
        }
        i {
          color: #fff;
          font-size: 47px;
        }
      }
      i {
        font-size: 37px;
        color: #333;
      }
    }
  }

  .talk_right_box {
    height: 100%;
    width: 100%;
    display: flex;
    flex-direction: column;
    position: relative;
    .content_box {
      width: 100%;
      flex-grow: 1; /* 高度填充剩余空间 */
      padding: 10px 20px 90px;
      box-sizing: border-box;
      overflow: auto;
      .content {
        width: 100%;
        .talk {
          width: 100%;
          margin-top: 10px;
          .talk_item {
            width: 100%;

            .tall_img {
              width: 45px;
              height: 45px;
              background-color: #fff;
              border-radius: 50%;

              img {
                width: 100%;
                height: 100%;
                border-radius: 50%;
              }
            }

            .tall_text {
              max-width: calc(100% - 45px - 45px);
              margin-left: 15px;
              margin-top: 43px;
              position: relative;

              .talk_name {
                position: absolute;
                top: -32px;
                left: 2px;
                display: flex;
                align-items: center;
                height: 30px;
                font-size: 15px;
                font-weight: 500;
                letter-spacing: 1px;
                white-space: nowrap;
              }

              .text_item {
                height: 100%;
                width: 100%;
                position: relative;
                .text_item_item {
                  line-height: 24px;
                  white-space: pre-wrap;
                  letter-spacing: 1px;
                  word-break: break-all;
                  position: relative;
                  background-color: #fff;
                  font-size: 14px;
                  padding: 10px 0px 10px;
                  box-sizing: border-box;
                  border-radius: 10px;
                  width: 100%;

                  .markdown_box {
                    .strong {
                      color: red !important;
                    }
                  }

                  img {
                    max-width: 100%;
                  }
                  .cursor_loding {
                    display: flex;
                    align-items: center;
                  }
                  .file_box {
                    display: flex;
                    flex-wrap: wrap;
                    .file_item {
                      margin-right: 5px;
                      margin-bottom: 8px;
                      width: 160px;
                      display: flex;
                      border: 1px solid #cdcdcd;
                      border-radius: 5px;
                      padding: 6px 5px;
                      cursor: pointer;
                      justify-content: space-between;
                      align-items: center;
                      box-sizing: border-box;
                      background-color: rgb(243 244 246);
                      transition: box-shadow 0.2s ease-in-out;
                      position: relative;

                      &:hover {
                        background-color: rgb(243 244 246);

                        box-shadow:
                          0px 0px 0px 0.5px #dce0e9,
                          0px 4px 8px 0px rgba(144, 150, 174, 0.1);
                      }
                      .file_icon {
                        width: 32px;
                        height: 35px;
                        img {
                          width: 100%;
                          height: 100%;
                        }
                      }
                      .file_text {
                        width: calc(100% - 40px);
                        height: 100%;
                        display: flex;
                        flex-direction: column;
                        justify-content: center;
                        padding-left: 5px;
                        box-sizing: border-box;
                        .file_name {
                          font-size: 13px;
                          color: #333;
                          overflow: hidden;
                          text-overflow: ellipsis;
                          white-space: nowrap;
                          max-width: 100%;
                        }
                        .file_size {
                          font-size: 12px;
                          color: #949494;
                        }
                      }
                    }
                  }
                }

                .Collection-of-buttons {
                  display: flex;
                  width: 100%;
                  margin-top: 10px;

                  .like_buttons {
                    display: flex;
                    align-items: center;
                    justify-content: flex-start;
                    margin-right: 20px;

                    .slot {
                      width: 1px;
                      height: 70%;
                      background-color: #ccc;
                      margin-right: 5px;
                      margin-top: 2px;
                    }
                    .like_icon {
                      width: 15px;
                      cursor: pointer;
                      color: white;
                    }

                    .like_text {
                      font-size: 12px;
                      margin-left: 3px;
                      cursor: pointer;
                    }
                  }
                }

                .home-LikeDom {
                  width: 100%;
                  border-radius: 10px;
                  padding: 15px 20px;
                  border: 1px solid #ebebeb;
                  margin: 25px 0 10px 0;
                }

                .like_allbox {
                  width: 100%;
                  background-color: #fff;
                  display: flex;
                  // justify-content: space-between;
                  margin-top: 6px;
                  padding-right: 5px;
                  box-sizing: border-box;
                  i {
                    user-select: none; /* Chrome, Safari, and Opera */
                    -moz-user-select: none; /* Firefox */
                    -ms-user-select: none; /* Internet Explorer/Edge */
                  }
                  .like_box {
                    height: 25px;
                    width: 58px;
                    border-radius: 13px;
                    background-color: #fff;
                    font-size: 12px;
                    display: flex;
                    align-items: center;
                    padding: 0 7px;
                    box-sizing: border-box;
                    justify-content: space-between;

                    .iconfont {
                      cursor: pointer;

                      &:hover {
                        color: #409eff;
                      }
                    }

                    .fg_box {
                      width: 1px;
                      height: 62%;
                      background-color: #333;
                      opacity: 0.5;
                    }
                  }
                  .more_question_box {
                    width: 100%;
                    display: flex;
                    justify-content: space-between;
                  }
                }
              }
            }
          }
          .talk_q {
            //默认从左侧，所以talk_q设置justify-content: end;
            display: flex;
            justify-content: flex-end;
            .tall_text {
              margin-right: 15px;
              margin-left: 0px;
              justify-content: flex-end;

              .talk_name {
                right: 7px !important;
                left: auto !important;
              }
            }
          }
        }
      }
    }

    .input_box {
      width: 100%;
      padding: 10px 25px; // 调整padding
      box-sizing: border-box;
      position: fixed;
      bottom: 0;
      right: 0;
      background-color: #ffffff;

      .upload_box {
        height: 47px;
        width: 100%;
        background-color: #ffffff;
        padding: 0 5px;
        display: flex;

        .upload_button {
          width: 90px;
          height: 30px;
          display: flex;
          justify-content: center;
          align-items: center;
          box-sizing: border-box;
          background-color: #409eff;
          border-radius: 12px;
          cursor: pointer;
          color: #fff;
          margin: 10px 15px 0 0;

          span {
            font-size: 12px;
            margin-left: 4px;
          }

          &:hover {
            opacity: 0.8;
          }
        }
      }
      .file_box {
        display: flex;

        flex-wrap: wrap;
        .file_item {
          margin-right: 5px;
          margin-bottom: 8px;
          width: 160px;
          display: flex;
          border: 1px solid #cdcdcd;
          border-radius: 5px;
          padding: 6px 5px;
          cursor: pointer;
          justify-content: space-between;
          align-items: center;
          box-sizing: border-box;
          background-color: rgb(243 244 246);
          transition: box-shadow 0.2s ease-in-out;
          position: relative;
          .del_box {
            display: none;
            position: absolute;
            top: 2px;
            right: 5px;
            cursor: pointer;
            color: red;
            font-size: 12px;
            width: 15px;
            height: 15px;
            text-align: center;
            border-radius: 50%;
          }
          .del_box:hover {
            color: #fff;
            background-color: red;
          }
          &:hover {
            background-color: rgb(243 244 246);

            box-shadow:
              0px 0px 0px 0.5px #dce0e9,
              0px 4px 8px 0px rgba(144, 150, 174, 0.1);
            .del_box {
              display: block !important;
            }
          }
          .file_icon {
            width: 32px;
            height: 35px;
            img {
              width: 100%;
              height: 100%;
            }
          }
          .file_text {
            width: calc(100% - 40px);
            height: 100%;
            display: flex;
            flex-direction: column;
            justify-content: center;
            padding-left: 5px;
            box-sizing: border-box;
            .file_name {
              font-size: 13px;
              color: #333;
              overflow: hidden;
              text-overflow: ellipsis;
              white-space: nowrap;
              max-width: 100%;
            }
            .file_size {
              font-size: 12px;
              color: #949494;
            }
          }
        }
      }
      .input_item {
        background-color: #fff;
        width: 100%;
        height: 70px;
        padding: 20px 20px 0;
        box-sizing: border-box;
        border-radius: 10px !important;
        border: 1px solid #e0e0e0;

        .input {
          width: 100%;
          height: 40px;
          overflow-y: auto;

          .txt-word {
            width: 100%;
            min-height: 24px;
            max-height: 72px;
            overflow: auto;
            color: #333;
            font-size: 15px;
            -webkit-user-modify: read-write-plaintext-only;
          }

          .txt-word:focus {
            outline: none;
          }

          /* 输入框为空时显示 placeholder empty无子元素*/
          .txt-word:empty:before {
            content: attr(placeholder);
            color: rgb(164, 164, 164);
          }

          /* 输入框获取焦点时移除 placeholder */
          .txt-word:focus:before {
            content: none;
          }
        }

        .button_box {
          height: 56px;
          width: 100%;
          display: flex;
          align-items: center;
          justify-content: flex-end;

          .image {
            width: 32px;
            height: 32px;
            cursor: pointer;
            transform: translateY(-50px);
          }
        }

        .file_box_button {
          background-color: #f0f2f5;
          width: 210px;
          height: 70px;
          margin-bottom: 15px;
          margin-top: -5px;
          display: flex;
          align-items: center;
          justify-content: space-between;
          padding: 6px 13px 1px;
          box-sizing: border-box;
          border-radius: 10px;
          box-shadow:
            rgba(0, 0, 0, 0.12) 0px 2px 1px,
            rgba(0, 0, 0, 0.04) 0px 0px 0px;
          position: relative;

          .del_box {
            // display: none;
            position: absolute;
            top: 2px;
            right: 5px;
            cursor: pointer;
            color: red;
            font-size: 12px;
            width: 15px;
            height: 15px;
            text-align: center;
          }

          // &:hover {
          //     .del_box {
          //         display: block !important;
          //     }
          // }

          .file_box_button_img {
            width: 30px;
            height: 30px;

            img {
              width: 100%;
              height: 100%;
            }
          }

          .file_box_button_name {
            width: calc(100% - 40px);
            height: 100%;

            .name_item {
              width: 100%;
              overflow: hidden;
              text-overflow: ellipsis;
              -webkit-line-clamp: 1;
              // display: -webkit-box;
              -webkit-box-orient: vertical;
              // font-family: cursive;
              white-space: nowrap;
              line-height: 40px;
              font-size: 13px;
            }

            .size_item {
              font-size: 12px;
              color: #949494;
            }
          }
        }
      }
    }
    .video_box {
      position: fixed;
      bottom: 80px;
      right: 0;
      width: 100%;
      height: 60px;
      background-color: #fff;
      display: flex;
      align-items: center;
      position: relative;
      .video_box_button_box {
        position: absolute;
        top: calc(100% - 95px);
        left: 8px;
        display: flex;
        .upload_button {
          width: 90px;
          height: 30px;
          display: flex;
          justify-content: center;
          align-items: center;
          box-sizing: border-box;
          background-color: #409eff;
          border-radius: 12px;
          cursor: pointer;
          color: #fff;
          margin-right: 15px;

          span {
            font-size: 12px;
            margin-left: 4px;
          }

          &:hover {
            opacity: 0.8;
          }
        }
      }
      .keyboard_box {
        height: 100%;
        width: 40px;
        display: flex;
        align-items: center;
        justify-content: center;
        .keyboard_inco {
          font-size: 27px;
          cursor: pointer;
        }
      }
      .video_item {
        -webkit-user-select: none;
        user-select: none;
        height: 100%;
        width: calc(100% - 40px);
        padding: 12px 12px 12px 5px;
        box-sizing: border-box;
        position: relative;
        .video_keyboard {
          background-color: #f0f2f5;
          width: 100%;
          height: 100%;
          border-radius: 5px;
          text-align: center;
          line-height: 36px;
          cursor: pointer;
          font-size: 15px;
          letter-spacing: 1px;
          color: #333;
        }
        .video_keyboard_copy {
          position: absolute;
          top: 10px;
          left: 0;
          width: 100%;
          height: 36px;
          z-index: 999;
          cursor: pointer;
          // background-color: #409eff;
        }
      }
    }
  }
}
</style>
